/*****************************************************************************
 * $LastChangedDate: 2011-09-19 21:23:09 -0400 (Mon, 19 Sep 2011) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   Functions to convert physical metrics.
 * @remarks physics/conversion.hh converts between different physical units.
 *          world/conversion.hh converts between graphical coordinates.
 *//*
 * LEGAL:   COPYRIGHT (C) 2007 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
 *****************************************************************************/

#define PHYSICS_CONVERSION_CC 1
#include "base/module.hh"
using namespace base;
#include "world/module.hh"
using namespace world;
#include "physics/module.hh"
#include "physics/conversion.hh"

namespace physics {
namespace conv {

/*****************************************************************************
 * Kilometer/hour --> mile/hour.
 *****************************************************************************/
SpeedMPH
KPH2MPH( const SpeedKPH kph )
{
    return SpeedMPH(kph.FP() * defs::KILOMETER_MILE_RATIO);
}

/*****************************************************************************
 * Speed (meter/second) --> kilometer/hour.
 *****************************************************************************/
SpeedKPH
Speed2KPH( const Speed speed )
{
    fp meterPerHour = speed.FP() * 3600.0f;
    fp kilometerPerHour = meterPerHour / 1000.0f;
    return SpeedKPH(kilometerPerHour);
}

/*****************************************************************************
 * kilometer/hour --> Speed (meter/second).
 *****************************************************************************/
Speed
KPH2Speed( const SpeedKPH kph )
{
    fp meterPerHour   = kph.FP() * 1000.0f;
    fp meterPerSecond = meterPerHour / 3600.0f;
    return Speed(meterPerSecond);
}

/*****************************************************************************
 * For a segment of time, convert physical speed to a scalar in graphical space.
 * This is used to translate the matrix of a 3D Object according to speed.
 *****************************************************************************/
fp
KPH2Step( const Milliseconds milliseconds, const SpeedKPH kph )
{
    // Zero time results in zero distance.
    if ( milliseconds > Milliseconds(0) )
    {
        // Use seconds as time unit, then convert to a fraction.
        const fpx seconds = Milliseconds2Seconds<fpx>( milliseconds.FPX() );  // fraction

        // Convert SpeedKPH to meters/second (Speed type).
        const Speed metersPerSecond = KPH2Speed( kph );

        // meter/sec * sec/1 = meter/1
        const Meter meters( metersPerSecond.FP() * seconds );

        // Convert meters to graphical space.
        return world::conv::Meters2Sim( meters );
    }
    else
    {
        return 0.0f;
    }
}

/*****************************************************************************
 * Speed (meter/sec) --> MPH.
 *****************************************************************************/
SpeedMPH
Speed2MPH( const Speed speed )
{
    SpeedKPH kph = Speed2KPH( speed );
    return KPH2MPH( kph );
}

/*****************************************************************************
 * Mach --> miles/hour
 *****************************************************************************/
SpeedMPH
Mach2MPH( const Mach mach )
{
    return SpeedMPH(mach.FP() * defs::MACH1_MPH);
}

/*****************************************************************************
 * Mach --> kilometer/hour
 *****************************************************************************/
SpeedKPH
Mach2KPH( const Mach mach )
{
    return SpeedKPH(mach.FP() * defs::MACH1_KPH);
}

/*****************************************************************************
 * Mach --> Speed (meter/sec)
 *****************************************************************************/
Speed
Mach2Speed( const Mach mach )
{
    // Convert meter/sec to kilometer/hour.
    SpeedKPH kph = Mach2KPH( mach );
    return Speed( KPH2Speed( kph ) );
}

/*****************************************************************************
 * Speed (meter/sec) --> Mach
 *****************************************************************************/
Mach
Speed2Mach( const Speed speed )
{
    // Convert KPH to Mach.
    return Mach(Speed2KPH(speed).FP() / defs::MACH1_KPH);
}

} // namespace conv
} // namespace physics
